﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
#include<list>
#include<map>
#include<assert.h>
using namespace std;

//struct Point
//{
//	int _x;
//	int _y;
//};
//
////int main()
////{
////	int a1[] = { 1, 2, 3, 4, 5 };
////	int a2[5] = { 0 };
////	Point p = { 1, 2 };
////	return 0;
////}
//
////int main()
////{
////	int x1 = 1;
////	int x2{ 2 };
////	int a1[]{ 1, 2, 3, 4, 5 };
////	int a2[5]{ 0 };
////	Point p{ 1, 2 };
////	return 0;
////}
//
//class Date
//{
//public:
//	Date(int year, int month, int day)
//		:_year(year)
//		, _month(month)
//		,_day(day)
//	{
//		cout << "Date(int year, int month, int day)" << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
////int main()
////{
////	Date d1(2022, 1, 1);
////
////	Date d2{ 2022, 1, 2 };
////	Date d3 = { 2022, 1, 2 };
////	return 0;
////}
//
////int main()
////{
////	auto il = { 10, 20 ,30 };
////	cout << typeid(il).name() << endl;
////	return 0;
////}
//
////int main()
////{
////	vector<int> v{ 1, 2, 3, 4 };
////	list<int> lt{ 1, 2 };
////	map<string, string> sict = { {"sort", "排序"}, {"inset", "插入"} };
////
////	v = { 1, 2, 3 };
////	return 0;
////}
//
////int main()
////{
////	//多参数构造类型转换: 构造+拷贝构造-> 直接构造.
////	Date d2 = { 2023, 11, 25 };
////	auto il1 = { 10, 20, 30, 40, 50 };
////
////	initializer_list<int> il2 = { 11, 22, 33 };
////
////	initializer_list<int>::iterator it2 = il2.begin();
////	//while (it2 != il2.end())
////	//{
////	//	cout << *it2 << endl;
////	//	it2++;
////	//}
////	//cout << endl;
////
////	for (auto e : il2)
////	{
////		cout << e << " ";
////	}
////	cout << endl;
////	return 0;
////}
//
////int main()
////{
////	int i = 1;
////	double d = 2.2;
////
////	/*cout << typeid(i).name() << endl;
////	cout << typeid(d).name() << endl;*/
////
////	auto j = i;
////	auto ret = i * d;
////	decltype(ret) x;
////
////	vector<decltype(ret)> v;
////	v.push_back(1);
////	v.push_back(1.1);
////
////	for (auto e : v)
////	{
////		cout << e << " ";
////	}
////	cout << endl;
////	return 0;
////}
//
////int main()
////{
////	//左值
////	int* p = new int(0);
////	int  b = 1;
////	const int c = 2;
////
////	//左值引用:
////	int*& rp = p;
////	int& rb = b;
////	const int& rc = c;
////	int& pvalue = *p;
////	return 0;
////}
//
////int main()
////{
////	double x = 1.1, y = 2.2;
////
////	10;
////	x + y;
////	fmin(x, y);
////
////	int&& rr1 = 10;
////	int&& rr2 = x + y;
////	int&& rr3 = fmin(x, y);
////	return 0;
////}
//
////int main()
////{
////	double x = 1.1, y = 2.2;
////	int&& rr1 = 10;
////	const double&& rr2 = x + y;
////	rr1 = 20;
////	rr2 = 5.5;  // 报错
////	return 0;
////}
//
////int main()
////{
////	//左值引用
////	int a = 10;
////	int& ra1 = a;
////
////	const int& ra2 = 10;
////	const int& ra2 = a;
////	
////	//右值引用
////	int&& aa1 = 10;
////	int a = 10;
////	int&& aa2 = move(a);
////
////	return 0;
////}
//
//
//namespace study
//{
//	class string
//	{
//		typedef char* iterator;
//		iterator begin()
//		{
//			return _str;
//		}
//
//		iterator end()
//		{
//			return _str + _size;
//		}
//
//		//构造函数
//		string(const char* str = "")
//			: _size(strlen(str))
//			, _capacity(_size)
//		{
//			_str = new char[_capacity + 1];
//			strcpy(_str, str);
//		}
//
//		// s1.swap(s2)
//		void swap(string& s)
//		{
//			::swap(_str, s._str);
//			::swap(_size, s._size);
//			::swap(_capacity, s._capacity);
//		}
//
//		// 拷贝构造
//		string(const string& s)
//			:_str(nullptr)
//		{
//			cout << "string(const string& s) -- 深拷贝" << endl;
//			string tmp(s._str);
//			swap(tmp);
//		}
//
//		string& operator=(const string& s)
//		{
//			cout << "string& operator=(string s) -- 深拷贝" << endl;
//			string tmp(s);
//			swap(tmp);
//			return *this;
//		}
//
//
//		~string()
//		{
//			delete[] _str;
//			_str = nullptr;
//		}
//
//		char& operator[](size_t pos)
//		{
//			assert(pos < _size);
//			return _str[pos];
//		}
//
//		void reserve(size_t n)
//		{
//			if (n > _capacity)
//			{
//				char* tmp = new char[n + 1];
//				strcpy(tmp, _str);
//				delete[] _str;
//				_str = tmp;
//				_capacity = n;
//			}
//		}
//
//		void push_back(char ch)
//		{
//			if (_size >= _capacity)
//			{
//				size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
//				reserve(newcapacity);
//			}
//			_str[_size] = ch;
//			++_size;
//			_str[_size] = '\0';
//		}
//
//		//string operator+=(char ch)
//		string& operator+=(char ch)
//		{
//			push_back(ch);
//			return *this;
//		}
//
//		const char* c_str() const
//		{
//			return _str;
//		}
//
//		//移动构造
//		string(string&& s)
//		{
//			cout << "string(string&& s)   --- 移动构造" << endl;
//			swap(s);
//		}
//
//		//移动赋值
//		string& operator=(string&& s)
//		{
//			cout << "string& operator=(const string& s) -- 移动赋值" << endl;
//			swap(s);
//			return *this;
//		}
//	private:
//		iterator _str;
//		size_t _size;
//		size_t _capacity;
//	};
//}
//
//string to_string(int value)
//{
//	string str;
//	//...
//	return str;
//}

//int main()
//{
//	string ret2 = to_string(-123);
//	return 0;
//}

//void Fun(int& x) { cout << "左值引用" << endl; }
//void Fun(const int& x) { cout << "const 左值引用" << endl; }
//
//void Fun(int&& x) { cout << "右值引用" << endl; }
//void Fun(const int&& x) { cout << "const 右值引用" << endl; }
//
//template<typename T>
//void perfectForward(T&& t)
//{
//	Fun(forward<T>(t));
//}

//int main()
//{
//	//右值
//	perfectForward(10);
//	
//	//左值
//	int a;
//	perfectForward(a);
//	perfectForward(move(a));
//
//	//左值
//	const int b = 9;
//	perfectForward(b);
//	perfectForward(move(b));
//
//	return 0;
//}
//
//template<class T>
//struct ListNode
//{
//	ListNode* _next = nullptr;
//	ListNode* _prev = nullptr;
//	T _data;
//};
//template<class T>
//class List
//{
//	typedef ListNode<T> Node;
//public:
//	List()
//	{
//		_head = new Node;
//		_head->_next = _head;
//		_head->_prev = _head;
//	
//
//	void PushBack(T&& x)
//	{
//		//Insert(_head, x);
//		Insert(_head, std::forward<T>(x));
//	}
//
//	void PushFront(T&& x)
//	{
//		//Insert(_head->_next, x);
//		Insert(_head->_next, std::forward<T>(x));
//	}
//
//	void Insert(Node* pos, T&& x)
//	{
//		Node* prev = pos->_prev;
//		Node* newnode = new Node;
//		newnode->_data = std::forward<T>(x); // 关键位置
//		// prev newnode pos
//		prev->_next = newnode;
//		newnode->_prev = prev;
//		newnode->_next = pos;
//		pos->_prev = newnode;
//	}
//
//	void Insert(Node* pos, const T& x)
//	{
//		Node* prev = pos->_prev;
//		Node* newnode = new Node;
//		newnode->_data = x; // 关键位置
//		// prev newnode pos
//		prev->_next = newnode;
//		newnode->_prev = prev;
//		newnode->_next = pos;
//		pos->_prev = newnode;
//	}
//
//private:
//	Node* _head;
//};
//int main()
//{
//	List<string> lt;
//	lt.PushBack("1111");
//	lt.PushFront("2222");
//	return 0;
//}

//class Person
//{
//public:
//	Person(const char* name = "", int age = 0)
//		:_name(name)
//		, _age(age)
//	{}
//	Person(const Person& p)
//		:_name(p._name)
//		, _age(p._age)
//	{}
//
//	Person(Person&& p) = default;
//private:
//	bit::string _name;
//	int _age;
//};
//int main()
//{
//	Person s1;
//	Person s2 = s1;
//	Person s3 = std::move(s1);
//	return 0;
//}

template <class T>
void PrintArg(T t)
{
	cout << t << " ";
}
//展开函数
template <class ...Args>
void ShowList(Args... args)
{
	int arr[] = { (PrintArg(args), 0)... };
	cout << endl;
}
//int main()
//{
//	ShowList(1);
//	ShowList(1, 'A');
//	ShowList(1, 'A', std::string("sort"));
//	return 0;
//}

//int main()
//{
//	//啥都不做
//	[] {};
//
//	//捕捉=上下的变量,返回值类型推到为int.
//	int a = 3, b = 4;
//	[=] {return a + 3; };
//
//	//没有返回值, 捕捉&的上下文变量, 然后用到函数体里面
//	/*auto fun1 = [&](int c) {b = a + c; };
//	fun1(10);
//	cout << a << " " << b << endl;*/
//
//	/*auto fun2 = [=, &b](int c)->int{return b += a + c; };
//	cout << fun2(10) << endl;*/
//
//	int x = 10;
//	auto add_x = [x](int a)mutable {x *= 2; return a + x; };
//	cout << typeid(add_x).name() << endl;
//	cout << add_x(10) << endl;
//}

class Rate
{
public:
	Rate(double rate) : _rate(rate)
	{}

	double operator()(double money, int year)
	{
		return money * _rate * year;
	}
private:
	double _rate;
};

//int main()
//{
//	// 函数对象
//	double rate = 0.49;
//	Rate r1(rate);
//	r1(10000, 2);
//	// lamber
//	auto r2 = [=](double monty, int year)->double {return monty * rate * year;
//	};
//	r2(10000, 2);
//	return 0;
//}

//函数模板
template<class F, class T>
T useF(F f, T x)
{
	static int count = 0;
	cout << "count:" << ++count << endl;
	cout << "count:" << &count << endl;
	return f(x);
}

//函数
double f(double i)
{
	return i / 2;
}

//仿函数
struct Functor
{
	double operator()(double d)
	{
		return d / 3;
	}
};

//int main()
//{
//	 函数名
//	cout << useF(f, 11.11) << endl;
//	 函数对象
//	cout << useF(Functor(), 11.11) << endl;
//	 lamber表达式
//	cout << useF([](double d)->double { return d / 4; }, 11.11) << endl;
//	return 0;
//}

#include <functional>
int f(int a, int b)
{
	return a + b;
}

//struct Functor
//{
//public:
//	int operator() (int a, int b)
//	{
//		return a + b;
//	}
//};

class Plus
{
public:
	static int plusi(int a, int b)
	{
		return a + b;
	}

	double plusd(double a, double b)
	{
		return a + b;
	}
};

//int main()
//{
//	// 成员函数取地址，比较特殊，要加一个类域和&
//	function<int(int, int)> f1 = &Plus::plusi;
//	cout << f1(1, 2) << endl;
//
//	function<double(Plus*, double, double)> f2 = &Plus::plusd;
//	Plus ps;
//	cout << f2(&ps, 1.1, 2.2) << endl;
//
//	function<double(Plus, double, double)> f3 = &Plus::plusd;
//	cout << f3(Plus(), 1.11, 2.22) << endl;
//
//	function<double(double, double)> f4 = bind(&Plus::plusd, Plus(), placeholders::_1, placeholders::_2);
//	cout << f4(1.11, 2.22) << endl;
//
//	return 0;
//}

#include <functional>
int Plus(int a, int b)
{
	return a + b;
}

class Sub
{
public:
	int sub(int a, int b)
	{
		return a - b;
	}
};

int main()
{
	//表示绑定函数plus 参数分别由调用 func1 的第一，二个参数指定
	function<int(int, int)> func1 = std::bind(Plus, placeholders::_1, placeholders::_2);

	auto func2 = std::bind(Plus, 1, 2);
	cout << func1(1, 2) << endl;
	cout << func2() << endl;
	 
	Sub s;
	//// 绑定成员函数
	function<int(int, int)> func3 = std::bind(&Sub::sub, s,	placeholders::_1, placeholders::_2);
	
	
	//// 参数调换顺序
	//std::function<int(int, int)> func4 = std::bind(&Sub::sub, s,
	//	placeholders::_2, placeholders::_1);
	//cout << func3(1, 2) << endl;
	//cout << func4(1, 2) << endl;

	return 0;
}